Popular Searches
Popular Course Categories
Popular Courses

Using the super Keyword and Constructor Chaining

Using the super Keyword and Constructor Chaining

Encapsulation, Inheritance, and Polymorphism

Using the super Keyword and Constructor Chaining in Java

Course: Core Java Training

Topic: Using the super Keyword and Constructor Chaining

Course Link: Core Java Training Course

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction

In Java, inheritance allows one class to acquire accessible members from another class. When working with inheritance, developers often need to initialize parent-class data, call inherited behavior, and coordinate the initialization of objects across multiple classes. Java provides the super keyword and constructor chaining to help accomplish these tasks.

The super keyword refers to the superclass portion of the current object. It can be used to invoke a superclass constructor, call an inherited method implementation, or access a superclass field hidden by a field declared in the subclass.

Constructor chaining is the process of calling one constructor from another constructor, either within the same class or through a superclass. It helps reuse initialization logic and ensures that superclass state is initialized as part of constructing a subclass object.

Learning Objectives

  • Understand the purpose and uses of the super keyword.
  • Learn how to call superclass constructors with super().
  • Understand the difference between this() and super().
  • Learn how constructors execute in an inheritance hierarchy.
  • Implement constructor chaining using single and multilevel inheritance.
  • Identify common constructor errors and follow best practices.

2. What Is the super Keyword?

The super keyword is used within a subclass to refer to superclass members. It is particularly useful when a subclass overrides a method, declares a field with the same name as a superclass field, or needs to initialize superclass data through a constructor.

Consider a parent class named Animal and a child class named Dog. The Dog class may have its own implementation of a method such as makeSound(). If it needs to execute the original implementation from Animal, it can call super.makeSound().

Main Uses of super

  • Calling a superclass constructor: Use super() or super(arguments).
  • Calling a superclass method: Use super.methodName().
  • Accessing a hidden superclass field: Use super.fieldName when a subclass field hides a field with the same name.

3. Using super to Call a Superclass Constructor

A subclass constructor can invoke a constructor of its direct superclass by using super(). If the superclass constructor requires arguments, those arguments are supplied inside the parentheses.

Syntax

class Parent {
    Parent() {
        System.out.println("Parent constructor");
    }
}

class Child extends Parent {
    Child() {
        super();
        System.out.println("Child constructor");
    }
}

In this example, super() invokes the no-argument constructor of Parent before the body of the Child constructor executes.

Output

Parent constructor
Child constructor

For traditional Java constructor syntax, an explicit super(...) invocation appears at the beginning of the constructor body. Java 25 and later also support flexible constructor bodies, which permit certain statements before an explicit constructor invocation subject to language restrictions. For typical Core Java programs, using super(...) as the first statement remains a clear and widely compatible practice.

4. Calling a Parameterized Superclass Constructor

Sometimes a superclass needs information to initialize its fields. In that situation, the subclass can pass values to a parameterized superclass constructor using super(arguments).

Example

class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;

        System.out.println("Person constructor executed.");
    }
}

class Student extends Person {
    int rollNumber;

    Student(String name, int age, int rollNumber) {
        super(name, age);
        this.rollNumber = rollNumber;

        System.out.println("Student constructor executed.");
    }

    void display() {
        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
        System.out.println("Roll Number: " + rollNumber);
    }
}

public class SuperConstructorDemo {
    public static void main(String[] args) {
        Student student = new Student("Aarav", 20, 101);
        student.display();
    }
}

Output:

Person constructor executed.
Student constructor executed.
Name: Aarav
Age: 20
Roll Number: 101

Explanation

  • Person defines a constructor that accepts a name and age.
  • Student extends Person and adds a roll number.
  • The super(name, age) statement passes the values to the superclass constructor.
  • The superclass initializes its fields before the subclass constructor continues.
  • The subclass initializes its own rollNumber field after the superclass constructor call.

5. Using super to Call a Parent Method

A subclass can override a superclass method and still invoke the original superclass implementation using super.methodName(). This is useful when the child class needs to preserve existing behavior and add extra functionality.

Example

class Employee {
    void displayRole() {
        System.out.println("General employee.");
    }
}

class Manager extends Employee {
    @Override
    void displayRole() {
        super.displayRole();
        System.out.println("Manages a team.");
    }
}

public class SuperMethodDemo {
    public static void main(String[] args) {
        Manager manager = new Manager();
        manager.displayRole();
    }
}

Output:

General employee.
Manages a team.

Explanation

  • Employee defines the original displayRole() method.
  • Manager overrides that method with additional behavior.
  • super.displayRole() invokes the superclass implementation.
  • The statement following the superclass call prints the manager-specific information.

6. Using super to Access a Hidden Field

A field declared in a subclass can have the same name as a field in its superclass. This is called field hiding. Within the subclass, the superclass field can be referenced using super.fieldName.

Example

class Parent {
    String message = "Message from Parent";
}

class Child extends Parent {
    String message = "Message from Child";

    void displayMessages() {
        System.out.println(message);
        System.out.println(super.message);
    }
}

public class SuperFieldDemo {
    public static void main(String[] args) {
        Child child = new Child();
        child.displayMessages();
    }
}

Output:

Message from Child
Message from Parent

The first statement accesses the field declared in Child. The second explicitly accesses the field declared in Parent.

Best practice: Avoid declaring fields with the same name in a parent and child class unless there is a specific reason. Field hiding can make programs harder to understand.

7. What Is Constructor Chaining?

Constructor chaining is the process of one constructor invoking another constructor as part of object initialization. In Java, constructor chaining can happen in two main ways:

  • Within the same class: One constructor invokes another constructor using this(...).
  • Across a class hierarchy: A subclass constructor invokes its direct superclass constructor using super(...).

Constructor chaining reduces duplicate initialization code and helps ensure that each class initializes its own data correctly.

Basic Constructor Chaining Structure

class A {
    A() {
        System.out.println("A constructor");
    }
}

class B extends A {
    B() {
        super();
        System.out.println("B constructor");
    }
}

class C extends B {
    C() {
        super();
        System.out.println("C constructor");
    }
}

When a C object is created, Java initializes the superclass hierarchy from the highest relevant superclass down to the subclass.

8. Constructor Chaining Within the Same Class Using this()

The this() constructor invocation calls another constructor in the same class. It is useful when several constructors share common initialization logic.

Example

class Product {
    String name;
    double price;

    Product() {
        this("Unknown", 0.0);
        System.out.println("Default constructor executed.");
    }

    Product(String name, double price) {
        this.name = name;
        this.price = price;
        System.out.println("Parameterized constructor executed.");
    }

    void display() {
        System.out.println("Product: " + name);
        System.out.println("Price: " + price);
    }
}

public class ThisConstructorDemo {
    public static void main(String[] args) {
        Product product = new Product();
        product.display();
    }
}

Output:

Parameterized constructor executed.
Default constructor executed.
Product: Unknown
Price: 0.0

Explanation

  • The no-argument constructor calls this("Unknown", 0.0).
  • The parameterized constructor initializes the fields.
  • After the parameterized constructor returns, the no-argument constructor continues executing.
  • The shared initialization logic is written once instead of being duplicated.

A constructor that uses this(...) must not create a direct or indirect cycle by calling itself through other constructors.

9. Difference Between this() and super()

Both this() and super() are used for constructor invocation, but they have different purposes.

Basis this() super()
Purpose Calls another constructor in the same class. Calls a constructor in the direct superclass.
Primary use Reuses initialization logic among constructors of one class. Initializes the superclass portion of a subclass object.
Arguments Must match a suitable constructor in the current class. Must match an accessible constructor in the direct superclass.
Inheritance requirement Does not require inheritance. Used when invoking a superclass constructor.
Constructor chaining Chains constructors within the same class. Chains constructors across the inheritance hierarchy.
Placement Must be used as the explicit constructor invocation in its permitted position. Must be used as the explicit superclass constructor invocation in its permitted position.

Important: A constructor cannot explicitly invoke both this(...) and super(...) as separate constructor-invocation statements. Calling another constructor using this(...) delegates the superclass initialization through that constructor's chain.

10. Understanding Constructor Execution Order

When a subclass object is created, Java initializes the superclass portion of the object before completing the subclass constructor body. In a multilevel inheritance hierarchy, this process continues through the superclass chain.

Example

class A {
    A() {
        System.out.println("Constructor A");
    }
}

class B extends A {
    B() {
        super();
        System.out.println("Constructor B");
    }
}

class C extends B {
    C() {
        super();
        System.out.println("Constructor C");
    }
}

public class ConstructorOrderDemo {
    public static void main(String[] args) {
        C obj = new C();
    }
}

Output:

Constructor A
Constructor B
Constructor C

Execution Steps

  1. The program creates an object of class C.
  2. The C constructor invokes the B constructor.
  3. The B constructor invokes the A constructor.
  4. The A constructor executes first.
  5. After A completes, the remaining body of B executes.
  6. Finally, the remaining body of C executes.

This ordering allows each superclass to initialize its part of the object before the subclass completes its own initialization.

11. Complete Example: Multilevel Constructor Chaining

This practical example uses a three-level hierarchy to demonstrate how constructor arguments are passed through successive superclass constructors.

class Person {
    String name;

    Person(String name) {
        this.name = name;
        System.out.println("Person initialized.");
    }
}

class Employee extends Person {
    int employeeId;

    Employee(String name, int employeeId) {
        super(name);
        this.employeeId = employeeId;
        System.out.println("Employee initialized.");
    }
}

class Manager extends Employee {
    String department;

    Manager(String name, int employeeId, String department) {
        super(name, employeeId);
        this.department = department;
        System.out.println("Manager initialized.");
    }

    void display() {
        System.out.println("Name: " + name);
        System.out.println("Employee ID: " + employeeId);
        System.out.println("Department: " + department);
    }
}

public class MultilevelChainingDemo {
    public static void main(String[] args) {
        Manager manager = new Manager(
            "Priya", 205, "Engineering"
        );

        manager.display();
    }
}

Output:

Person initialized.
Employee initialized.
Manager initialized.
Name: Priya
Employee ID: 205
Department: Engineering

Explanation

  • Person initializes the employee's name.
  • Employee invokes super(name) and initializes the employee ID.
  • Manager invokes super(name, employeeId) and initializes the department.
  • The constructor chain ensures that each class initializes the data it owns.
  • The final object contains the state and behavior defined across the hierarchy.

12. What Happens If super() Is Not Written?

If a constructor does not explicitly invoke another constructor using this(...) or super(...), Java normally inserts an implicit no-argument superclass constructor invocation where the language rules permit it.

Example

class Parent {
    Parent() {
        System.out.println("Parent constructor");
    }
}

class Child extends Parent {
    Child() {
        System.out.println("Child constructor");
    }
}

public class ImplicitSuperDemo {
    public static void main(String[] args) {
        new Child();
    }
}

Output:

Parent constructor
Child constructor

The Child() constructor does not explicitly contain super(), but Java inserts the implicit call to the no-argument constructor of Parent.

Important Case: No Default Constructor in the Parent

class Parent {
    Parent(String name) {
        System.out.println(name);
    }
}

class Child extends Parent {
    Child() {
        super("Java");
    }
}

Here, Child explicitly invokes the parameterized constructor of Parent. If the super("Java") statement were omitted, the compiler would attempt to use a no-argument superclass constructor, which does not exist, and the code would fail to compile.

13. Constructor Chaining and Field Initialization

Java initializes instance fields with their default values and then performs instance field initializers and instance initialization blocks as part of object construction. Constructor chaining coordinates superclass and subclass initialization. Understanding the order is important when constructors depend on field values.

For typical programs, remember these points:

  • Instance fields receive default values such as 0, false, or null before explicit initialization.
  • Superclass construction takes place before the subclass constructor body completes.
  • Instance field initializers and initialization blocks execute as part of the initialization process for their respective classes.
  • Use constructors to establish valid initial state.
  • Avoid calling overridable methods from constructors when possible, because a subclass implementation may execute before the subclass has completed its initialization.

14. Common Errors When Using super and Constructor Chaining

Error Cause Solution
Constructor cannot be applied to given types The arguments passed to super(...) do not match an accessible superclass constructor. Check the superclass constructor signature and pass compatible arguments.
Implicit super constructor is undefined The superclass has no accessible no-argument constructor. Invoke an available superclass constructor explicitly using super(arguments).
Constructor call must be first In traditional constructor syntax, statements appear before an explicit this(...) or super(...) call. Place the constructor invocation in the permitted position. Java 25 and later have additional flexible constructor-body rules.
Recursive constructor invocation Constructors call one another in a cycle using this(...). Redesign the constructor chain so that it eventually reaches a constructor that initializes the object without repeating the cycle.
Cannot reference this before supertype constructor The constructor uses the current instance before the required superclass construction step has been completed. Move instance-dependent operations until after the superclass constructor invocation.
Unexpected constructor output order The programmer assumes subclass constructors execute before superclass constructors. Trace the constructor chain from the superclass level toward the subclass level.

15. Best Practices for super and Constructor Chaining

  • Use super(...) to initialize superclass fields through the appropriate constructor.
  • Use this(...) to reuse constructor logic within the same class.
  • Avoid duplicating the same field-initialization logic in multiple constructors.
  • Ensure that each constructor establishes a valid object state.
  • Use the most suitable constructor rather than relying on a no-argument constructor that does not represent valid initialization.
  • Keep constructor chains easy to follow and avoid circular calls between constructors.
  • Use super.methodName() only when the superclass implementation is needed.
  • Avoid unnecessary field hiding because it can make code confusing.
  • Avoid calling overridable methods from constructors unless the implications are fully understood.
  • Test constructor behavior for valid arguments, invalid arguments, and different constructor overloads.

16. Practical Exercises

  1. Person and Student: Create a Person class with a parameterized constructor. Extend it with Student and initialize the parent fields using super().
  2. Vehicle and Car: Create a Vehicle constructor that accepts a brand. Extend it with Car, pass the brand to the superclass, and initialize the number of doors.
  3. Constructor overloading: Create a Product class with default and parameterized constructors. Use this() to reuse initialization logic.
  4. Three-level hierarchy: Create Person, Employee, and Manager classes. Print a message from each constructor to observe the execution order.
  5. Superclass method: Create a parent class with a display() method and override it in a child class. Use super.display() to execute both implementations.
  6. Constructor validation: Validate input in a superclass constructor and ensure that the subclass passes appropriate values through super(...).

17. Mini Project: Vehicle Registration System

Objective: Build a simple Java program that uses inheritance, the super keyword, and constructor chaining to initialize vehicle information.

Requirements

  • Create a Vehicle class with fields for brand and registration number.
  • Provide a parameterized constructor to initialize these fields.
  • Create a Car subclass with an additional field for the number of doors.
  • Use super(brand, registrationNumber) to initialize the superclass fields.
  • Create a ElectricCar subclass with a battery capacity field.
  • Use constructor chaining across all three levels.
  • Display all vehicle details using appropriate methods.
  • Validate that registration numbers and numeric values meet the program's requirements.

Expected Learning Outcomes

After completing the project, learners should understand how to pass constructor arguments across an inheritance hierarchy, reuse superclass initialization, and keep class-specific initialization in the appropriate constructor.

18. Core Java Interview Questions and Answers

Q1. What is the super keyword in Java?

Answer: The super keyword refers to the superclass portion of the current object. It can be used to call superclass constructors, invoke superclass methods, and access hidden superclass fields.

Q2. What is constructor chaining?

Answer: Constructor chaining is the process of one constructor invoking another constructor in the same class or a superclass to coordinate object initialization.

Q3. What is the difference between this() and super()?

Answer: this() invokes another constructor in the same class, while super() invokes a constructor in the direct superclass.

Q4. Why is super() used in a subclass constructor?

Answer: It invokes the superclass constructor so that the superclass portion of the object can be initialized with appropriate values.

Q5. What happens if super() is omitted?

Answer: Java normally inserts an implicit no-argument superclass constructor invocation if the constructor does not explicitly invoke another constructor and an accessible no-argument superclass constructor is available.

Q6. Can this() and super() both be used as separate calls in one constructor?

Answer: No. A constructor cannot contain both as separate explicit constructor-invocation statements. A constructor that calls this(...) delegates the superclass construction through the constructor it invokes.

Q7. Can a subclass call a parameterized superclass constructor?

Answer: Yes. It can use super(arguments) with arguments that match an accessible constructor in the direct superclass.

Q8. Can super be used to call an overridden method?

Answer: Yes. A subclass can use super.methodName() to invoke the superclass implementation of an overridden method.

Q9. Are constructors inherited in Java?

Answer: No. Constructors are not inherited. A subclass constructor invokes an appropriate superclass constructor as part of object initialization.

Q10. What is multilevel constructor chaining?

Answer: It occurs when a constructor in a subclass invokes its superclass constructor, which in turn invokes the next superclass constructor, continuing up the hierarchy.

Q11. Can super be used in a static method?

Answer: No. The ordinary forms of super that refer to the current object's superclass members require an instance context and cannot be used in a static method.

Q12. Why should overridable methods generally be avoided in constructors?

Answer: An overridden subclass implementation may execute before the subclass has completed initialization, potentially accessing fields that are not yet ready.

19. Quick Revision Notes

  • super() calls a superclass constructor.
  • super(arguments) calls a matching parameterized superclass constructor.
  • super.methodName() invokes a superclass method implementation.
  • super.fieldName accesses a hidden superclass field.
  • this() invokes another constructor in the same class.
  • Constructor chaining supports code reuse and structured initialization.
  • Superclass construction occurs before the subclass constructor body completes.
  • Constructors are not inherited.
  • If a superclass lacks an accessible no-argument constructor, the subclass must invoke an appropriate constructor explicitly.
  • A constructor chain must not contain a recursive cycle.
  • Use constructors to establish valid initial state and avoid unnecessary initialization duplication.

20. Conclusion

The super keyword and constructor chaining are important Core Java concepts for working with inheritance. The super keyword allows subclasses to invoke superclass constructors, access hidden fields, and reuse superclass method implementations. Constructor chaining allows related constructors to share initialization logic and ensures that each class in an inheritance hierarchy initializes its own state.

Practice these concepts with person, student, employee, manager, and vehicle examples. Focus on understanding the difference between this() and super(), constructor execution order, parameter passing, and the rules governing constructor calls.

Continue Learning with JustAcademy

Explore the Core Java Training Course to continue learning Java fundamentals, constructors, inheritance, polymorphism, and object-oriented programming.

Register for a Course Demo to learn more about the training, or visit the JustAcademy website.

Previous Next
whatsapp